﻿using FluentMigrator;
using FrameworkCore.Modules;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using FrameworkCore.Modules.Startups;
using FluentMigrator.Runner;
using FrameworkCore.Constants;
using FrameworkCore.Migrations;
using Infrastructure.Persistence;
using FrameworkCore.Repositories;
using FrameworkCore.Extensions;
using Infrastructure.Repositories;

namespace Infrastructure.Startups;

/// <summary>
/// 表示用于在应用程序启动时配置数据库上下文的对象
/// </summary>
public partial class AiBLSmartEduDbStartup : IAiBLSmartEduStartup
{
    /// <summary>
    /// 添加和配置任何中间件
    /// </summary>
    /// <param name="services">服务描述符的集合</param>
    /// <param name="configuration">应用程序的配置</param>
    public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
    {
        var connectionString = configuration.GetConnectionString(GlobalConstants.DefaultConnectionKey)!;
        var typeFinder = Singleton<ITypeFinder>.Instance;
        var mAssemblies = typeFinder.FindClassesOfType<MigrationBase>()
            .Select(t => t.Assembly)
            .Where(assembly => !assembly.FullName!.Contains("FluentMigrator.Runner"))
            .Distinct()
            .ToArray();

        //数据库迁移配置
        services
            .AddFluentMigratorCore() // 添加通用的 FluentMigrator 服务
            .ConfigureRunner(rb => rb
            .AddSqlServer()
            .WithGlobalConnectionString(connectionString)
            .ScanIn(mAssemblies).For.Migrations());// 定义包含迁移的程序集

        services.AddDbContextService(configuration);
        //数据库提供者
        services.AddScoped<IAiBLSmartEduDataProvider, EfCoreProvider>();
        //仓储
        services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

        //如果数据库不存在则创建,并且执行迁移
        using (var scope = services.BuildServiceProvider().CreateScope()) 
        {
            var dataProvider = scope.ServiceProvider.GetRequiredService<IAiBLSmartEduDataProvider>();
            dataProvider.CreateDatabaseIfNotExists(connectionString);

            var runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();
            try
            {
                runner.MigrateUp();
                Console.WriteLine($"完成迁移");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"迁移：{ex.Message}");
            }
        }    
    }

    /// <summary>
    /// 配置已添加中间件的使用
    /// </summary>
    /// <param name="application">用于配置应用程序请求管道的生成器</param>
    public void Configure(IApplicationBuilder application)
    {
    }

    /// <summary>
    /// 获取此启动配置实现的顺序
    /// </summary>
    public int Order => 10;
}